package com.yin.myproject.collection;

import java.util.NoSuchElementException;

/**
 * @author Eason
 * @create 2018-05-28 17:52
 **/
public class ArrayQueue<E> implements Queue<E> {

    /**
     * 数组存放元素
     */
    private transient Object[] elements;
    /**
     * 指向队首元素
     */
    private transient int head;
    /**
     * 指向队尾元素
     */
    private transient int tail;
    /**
     * 数组初始容量
     */
    private static final int MIN_INITIAL_CAPACITY = 8;

    /**
     * 指定数组初始容量
     */
    private int capacity;

    public ArrayQueue() {
        this.capacity = MIN_INITIAL_CAPACITY;
        this.elements = new Object[MIN_INITIAL_CAPACITY];
    }

    public ArrayQueue(int capacity) {
        this.capacity = capacity;
        this.elements = new Object[capacity];
    }

    @Override
    public boolean add(E e) {
        addLast(e);
        return true;
    }

    /**
     * 向数组最后位置添加元素
     *
     * @param e
     * @return
     */
    private void addLast(E e) {
        if (e == null)
            throw new NullPointerException();
        if ((tail = (tail + 1) & (elements.length - 1)) == head)
            throw new IllegalStateException();
        elements[tail] = e;
    }


    @Override
    public boolean offer(E e) {
        return offerLast(e);
    }

    private boolean offerLast(E e) {
        addLast(e);
        return true;
    }

    @Override
    public E remove() {
        return removeFirst();
    }

    private E removeFirst() {
        E x = pollFirst();
        if (x == null)
            throw new NoSuchElementException();
        return x;
    }

    private E pollFirst() {
        int h = head;
        E result = (E) elements[head];
        if (result == null)
            return null;
        elements[h] = null;
        h++;
        return result;
    }

    @Override
    public E poll() {
        return pollFirst();
    }

    @Override
    public E element() {
        return null;
    }

    @Override
    public E peek() {
        return null;
    }

    public static void main(String[] args) {
        ArrayQueue<Integer> arrayQueue = new ArrayQueue<>();
        System.out.println(arrayQueue.offer(1));
        System.out.println(arrayQueue.offer(2));
        System.out.println(arrayQueue.offer(3));
        System.out.println(arrayQueue.offer(4));
        System.out.println(arrayQueue.offer(5));
        System.out.println(arrayQueue.offer(6));
        System.out.println(arrayQueue.offer(7));
        System.out.println(arrayQueue.offer(8));

    }
}

